package xyz.ibenben.zhongdian.common.shiro;

import com.github.pagehelper.StringUtil;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.filter.mgt.DefaultFilterChainManager;
import org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver;
import org.apache.shiro.web.servlet.AbstractShiroFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import xyz.ibenben.zhongdian.common.exception.ExceptionEnum;
import xyz.ibenben.zhongdian.common.exception.MyException;
import xyz.ibenben.zhongdian.system.entity.sys.SysResources;
import xyz.ibenben.zhongdian.system.service.sys.SysResourcesService;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * @author chenjian
 * @since 2017年10月18日下午5:17:22
 */
@Service
public class ShiroService {
    /* Shiro过滤工厂实体 */
    @Autowired
    private ShiroFilterFactoryBean shiroFilterFactoryBean;

    /* 资源服务 */
    @Autowired
    private SysResourcesService sysResourcesService;

    /**
     * 初始化权限
     *
     * @return 返回值
     */
    private Map<String, String> loadFilterChainDefinitions() {
        // 权限控制map.从数据库获取
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();

        filterChainDefinitionMap.put("/", "user, addPrincipal");
        //在每个可以使用RememberMe功能进行访问的url上面都添加这个自定义的Filter
        filterChainDefinitionMap.put("/logout", "logout");
        filterChainDefinitionMap.put("/static/**", "anon");
        //这里设置调过权限判断的地址
        filterChainDefinitionMap.put("/login", "anon");
        filterChainDefinitionMap.put("/regist", "anon");
        filterChainDefinitionMap.put("/pwdBack", "anon");
        filterChainDefinitionMap.put("/getVerifyCode", "anon");
        filterChainDefinitionMap.put("/emailActivate", "anon");
        filterChainDefinitionMap.put("/resetPassword", "anon");
        filterChainDefinitionMap.put("/sendMessage", "anon");
        filterChainDefinitionMap.put("/getMessage", "anon");
        //获取权限资源
        List<SysResources> resourcesList = sysResourcesService.selectAll();
        for (SysResources resources : resourcesList) {
            if (StringUtil.isNotEmpty(resources.getResUrl())) {
                String permission = "perms[" + resources.getResUrl() + "]";
                filterChainDefinitionMap.put(resources.getResUrl(), permission);
            }
        }
        //加入到map里
        filterChainDefinitionMap.put("/index", "user, addPrincipal");//"authc"
        return filterChainDefinitionMap;
    }

    /**
     * 重新加载权限
     */
    public void updatePermission() {
        synchronized (shiroFilterFactoryBean) {
            AbstractShiroFilter shiroFilter;
            try {
                shiroFilter = (AbstractShiroFilter) shiroFilterFactoryBean.getObject();
            } catch (Exception e) {
                throw new MyException(ExceptionEnum.UNKONW_ERROR, e);
            }
            //获取管理器
            PathMatchingFilterChainResolver filterChainResolver = (PathMatchingFilterChainResolver) shiroFilter.getFilterChainResolver();
            DefaultFilterChainManager manager = (DefaultFilterChainManager) filterChainResolver.getFilterChainManager();

            // 清空老的权限控制
            manager.getFilterChains().clear();
            //清理
            shiroFilterFactoryBean.getFilterChainDefinitionMap().clear();
            //读取
            shiroFilterFactoryBean.setFilterChainDefinitionMap(loadFilterChainDefinitions());
            // 重新构建生成
            Map<String, String> chains = shiroFilterFactoryBean.getFilterChainDefinitionMap();
            for (Map.Entry<String, String> entry : chains.entrySet()) {
                String url = entry.getKey();
                String chainDefinition = entry.getValue().trim().replace(" ", "");
                manager.createChain(url, chainDefinition);
            }
        }
    }

}
